gabriel / musehub public
_diff.scss
538 lines 17.5 KB
Raw
sha256:9590cee1e0ccd6c76528f005b95d634d80f5019f0dcb7c371e149adc31d1fb65 refactor: enforce gRPC framing on all MWP wire traffic Sonnet 4.6 minor ⚠ breaking 156 days ago
1 // _diff.scss — Diff page (.diff-*, .df3-* prefixes)
2
3 // ── Diff page ─────────────────────────────────────────────────────────────────
4
5 .diff-page { padding-top: var(--space-4); }
6
7 .diff-commit-header-card {
8 margin-bottom: var(--space-3);
9 padding: var(--space-3) var(--space-4);
10 }
11
12 .diff-commit-meta {
13 display: flex; align-items: center; gap: var(--space-2);
14 flex-wrap: wrap; margin-bottom: var(--space-2);
15 }
16
17 .diff-commit-sha {
18 font-family: var(--font-mono); font-size: 12px; color: var(--color-accent);
19 background: color-mix(in srgb, var(--color-accent) 12%, transparent);
20 border-radius: 4px; padding: 1px 6px;
21 }
22
23 .diff-commit-branch {
24 font-size: 12px; color: var(--text-muted); font-family: var(--font-mono);
25 background: var(--bg-overlay); border-radius: 4px; padding: 1px 6px;
26 }
27
28 .diff-commit-author { font-size: 12px; color: var(--text-secondary); }
29
30 .diff-commit-msg {
31 font-size: 14px; font-weight: 500; color: var(--text-primary); margin-bottom: var(--space-1);
32 }
33
34 .diff-commit-parent { display: flex; align-items: center; gap: 6px; }
35
36 .diff-root-pill {
37 display: inline-block; font-size: 11px; color: var(--color-success);
38 background: color-mix(in srgb, var(--color-success) 12%, transparent);
39 border-radius: 4px; padding: 2px 8px;
40 }
41
42 .diff-root-badge {
43 font-size: 11px; color: var(--color-success);
44 }
45
46 .diff-parent-badge {
47 font-size: 11px; color: var(--text-muted);
48 }
49
50 .diff-parent-sha {
51 font-family: var(--font-mono); font-size: 11px; color: var(--color-accent);
52 }
53
54 // Two-panel layout: sidebar + viewer
55 .diff-layout {
56 display: grid;
57 grid-template-columns: 240px 1fr;
58 gap: var(--space-3);
59 align-items: start;
60 min-height: 70vh;
61 }
62
63 @media (max-width: 768px) {
64 .diff-layout { grid-template-columns: 1fr; }
65 .diff-file-tree { max-height: 200px; overflow-y: auto; }
66 }
67
68 // File tree sidebar
69 .diff-file-tree {
70 background: var(--bg-surface);
71 border: 1px solid var(--border-default);
72 border-radius: var(--radius-md);
73 overflow: hidden;
74 position: sticky;
75 top: 64px;
76 max-height: calc(100vh - 80px);
77 overflow-y: auto;
78 }
79
80 .diff-tree-header {
81 display: flex; align-items: center; gap: 6px;
82 padding: 8px 12px;
83 font-size: 11px; color: var(--text-muted); font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em;
84 border-bottom: 1px solid var(--border-subtle);
85 background: var(--bg-overlay);
86 position: sticky; top: 0; z-index: 1;
87 }
88
89 .diff-file-list {
90 list-style: none; margin: 0; padding: 4px 0;
91 }
92
93 .diff-file-item {
94 display: flex; align-items: center; gap: 6px;
95 padding: 5px 10px; cursor: pointer;
96 font-size: 12px; color: var(--text-secondary);
97 transition: background 0.1s, color 0.1s;
98 border-left: 2px solid transparent;
99 overflow: hidden;
100
101 &:hover { background: var(--bg-overlay); color: var(--text-primary); }
102 &.active {
103 background: color-mix(in srgb, var(--color-accent) 10%, transparent);
104 color: var(--color-accent);
105 border-left-color: var(--color-accent);
106 }
107 }
108
109 .diff-file-sign { flex-shrink: 0; width: 12px; font-family: var(--font-mono); color: var(--color-success); }
110 .diff-file-icon { flex-shrink: 0; font-size: 13px; }
111 .diff-file-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--font-mono); }
112 .diff-file-size { flex-shrink: 0; font-size: 10px; color: var(--text-muted); }
113
114 // Viewer panel
115 .diff-viewer {
116 background: var(--bg-surface);
117 border: 1px solid var(--border-default);
118 border-radius: var(--radius-md);
119 overflow: hidden;
120 min-height: 300px;
121 }
122
123 .diff-viewer-header {
124 display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px;
125 padding: 8px 12px;
126 background: var(--bg-overlay);
127 border-bottom: 1px solid var(--border-subtle);
128 position: sticky; top: 64px; z-index: 1;
129 }
130
131 .diff-file-path-bar {
132 display: flex; align-items: center; gap: 8px;
133 }
134
135 .diff-file-path-label {
136 font-family: var(--font-mono); font-size: 12px; color: var(--text-primary);
137 }
138
139 .diff-hunk-header {
140 display: flex; align-items: center; justify-content: space-between;
141 padding: 6px 12px;
142 background: color-mix(in srgb, var(--color-accent) 6%, transparent);
143 border-bottom: 1px solid var(--border-subtle);
144 font-size: 11px; color: var(--text-muted);
145 }
146
147 .diff-hunk-info { display: flex; align-items: center; gap: 8px; }
148
149 .diff-lang-badge {
150 font-family: var(--font-mono); font-size: 10px;
151 background: color-mix(in srgb, var(--color-accent) 15%, transparent);
152 color: var(--color-accent);
153 border-radius: 4px; padding: 1px 6px; text-transform: uppercase; letter-spacing: 0.04em;
154 }
155
156 .diff-code-panel { overflow-x: auto; }
157 .diff-code-scroll { overflow-x: auto; }
158
159 // Unified diff table
160 .diff-table {
161 width: 100%; border-collapse: collapse; font-family: var(--font-mono); font-size: 12.5px; line-height: 1.5;
162
163 td { padding: 0; border: none; vertical-align: top; white-space: pre; }
164 }
165
166 .diff-ln-sign {
167 width: 14px; min-width: 14px; text-align: center;
168 user-select: none; color: var(--color-success); opacity: 0.7;
169 padding: 0 3px;
170 }
171
172 .diff-ln-num {
173 width: 48px; min-width: 48px; text-align: right;
174 user-select: none; color: var(--text-muted); opacity: 0.5;
175 padding: 0 8px 0 0;
176 }
177
178 .diff-ln-code {
179 padding-left: 4px; color: var(--text-primary);
180 white-space: pre; overflow: visible;
181 // Allow hljs spans to render inline
182 span { display: inline; white-space: pre; }
183 }
184
185 .diff-line-add {
186 background: color-mix(in srgb, var(--color-success) 6%, transparent);
187 &:hover { background: color-mix(in srgb, var(--color-success) 12%, transparent); }
188 }
189
190 .diff-line-ctx { background: transparent; }
191
192 // Loading / error states
193 .diff-loading { padding: var(--space-5); color: var(--text-muted); font-size: 13px; }
194 .diff-empty { padding: var(--space-5); color: var(--text-muted); font-size: 13px; text-align: center; }
195 .diff-error { padding: var(--space-5); color: var(--color-danger); font-size: 13px; }
196
197 .spinner {
198 display: inline-block; width: 14px; height: 14px; margin-right: 6px;
199 border: 2px solid var(--border-default); border-top-color: var(--color-accent);
200 border-radius: 50%; animation: spin 0.6s linear infinite;
201 }
202 @keyframes spin { to { transform: rotate(360deg); } }
203
204 // highlight.js theme — dark, matching our tokens
205 .hljs { background: transparent; }
206 .hljs-keyword, .hljs-selector-tag, .hljs-title { color: var(--color-accent); font-weight: 600; }
207 .hljs-string, .hljs-attr { color: var(--color-success); }
208 .hljs-comment, .hljs-quote { color: var(--text-muted); font-style: italic; }
209 .hljs-number, .hljs-literal, .hljs-built_in { color: #f0883e; }
210 .hljs-name, .hljs-tag { color: #7ee787; }
211 .hljs-variable, .hljs-template-variable { color: #ffa657; }
212 .hljs-type, .hljs-class { color: #79c0ff; font-style: italic; }
213 .hljs-function, .hljs-subst { color: #d2a8ff; }
214 .hljs-params { color: var(--text-secondary); }
215 .hljs-section, .hljs-meta { color: #79c0ff; }
216 .hljs-addition { background: color-mix(in srgb, var(--color-success) 15%, transparent); }
217 .hljs-deletion { background: color-mix(in srgb, var(--color-danger) 15%, transparent); }
218
219
220
221 // Diff page v3 — df3-*
222 // ══════════════════════════════════════════════════════════════════════════════
223
224 .df3-page { max-width: 100%; }
225
226 // ── Header ─────────────────────────────────────────────────────────────────
227 .df3-header {
228 display: flex; align-items: center; gap: var(--space-3);
229 padding: var(--space-4) 0 var(--space-5);
230 border-bottom: 1px solid var(--border-subtle);
231 margin-bottom: var(--space-5);
232 flex-wrap: wrap;
233 }
234
235 .df3-back {
236 display: inline-flex; align-items: center; gap: 5px;
237 font-size: 11px; color: var(--text-muted); text-decoration: none;
238 background: var(--surface-2); border: 1px solid var(--border-default);
239 padding: 3px 8px; border-radius: var(--radius-sm);
240 &:hover { color: var(--color-accent-link); border-color: var(--color-accent); }
241 }
242
243 .df3-sha {
244 font-family: var(--font-mono); font-size: 12px;
245 color: var(--text-secondary); background: var(--surface-2);
246 padding: 2px 7px; border-radius: 4px;
247 }
248
249 .df3-branch {
250 display: inline-flex; align-items: center; gap: 4px;
251 font-size: 11px; color: var(--text-muted);
252 background: var(--surface-2); padding: 2px 7px; border-radius: 10px;
253 }
254
255 .df3-msg {
256 font-size: 13px; color: var(--text-primary); font-weight: 500;
257 white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
258 max-width: 600px;
259 }
260
261 // ── Stats bar ──────────────────────────────────────────────────────────────
262 .df3-stats-bar {
263 display: flex; align-items: center; justify-content: space-between;
264 flex-wrap: wrap; gap: var(--space-3);
265 margin-bottom: var(--space-5);
266 padding-bottom: var(--space-4);
267 border-bottom: 1px solid var(--border-subtle);
268 }
269
270 .df3-stats-row { display: flex; gap: var(--space-2); flex-wrap: wrap; }
271
272 .df3-stat {
273 display: flex; flex-direction: column; gap: 2px; min-width: 80px;
274 background: var(--surface-2); border: 1px solid var(--border-default);
275 border-radius: var(--radius-md); padding: var(--space-2) var(--space-3);
276 &.df3-stat-add { border-top: 2px solid #34d399; .df3-stat-n { color: #34d399; } }
277 &.df3-stat-mod { border-top: 2px solid #fbbf24; .df3-stat-n { color: #fbbf24; } }
278 &.df3-stat-del { border-top: 2px solid #f87171; .df3-stat-n { color: #f87171; } }
279 &.df3-stat-files{ border-top: 2px solid #8b5cf6; .df3-stat-n { color: #c084fc; } }
280 &.df3-stat-snap { border-top: 2px solid #475569; .df3-stat-n { color: var(--text-secondary); } }
281 &.df3-stat-clean{ border-top: 2px solid #34d399; .df3-stat-n { color: #34d399; } }
282 }
283
284 .df3-stat-n {
285 font-size: 20px; font-weight: 800; line-height: 1.1;
286 font-variant-numeric: tabular-nums; letter-spacing: -.02em;
287 }
288
289 .df3-stat-l {
290 font-size: 9px; color: var(--text-muted);
291 text-transform: uppercase; letter-spacing: .06em; white-space: nowrap;
292 }
293
294 .df3-stats-meta { font-size: 12px; color: var(--text-muted); }
295
296 .df3-vs { display: flex; align-items: center; gap: var(--space-2); }
297
298 .df3-parent-sha {
299 font-family: var(--font-mono); font-size: 11px;
300 color: var(--color-accent-link); text-decoration: none;
301 &:hover { text-decoration: underline; }
302 }
303
304 .df3-root-pill {
305 font-size: 10px; color: var(--text-muted);
306 background: var(--surface-3); padding: 2px 7px; border-radius: 10px;
307 }
308
309 // ── Files ──────────────────────────────────────────────────────────────────
310 .df3-content { display: flex; flex-direction: column; }
311 .df3-files { display: flex; flex-direction: column; gap: var(--space-4); }
312
313 .df3-file-card {
314 background: var(--surface-2); border: 1px solid var(--border-default);
315 border-radius: var(--radius-lg); overflow: hidden;
316
317 &.df3-file-added { border-left: 3px solid #22c55e; }
318 &.df3-file-removed { border-left: 3px solid #ef4444; }
319 &.df3-file-modified{ border-left: 3px solid #f59e0b; }
320 }
321
322 .df3-file-hd {
323 display: flex; align-items: center; gap: var(--space-2);
324 padding: var(--space-2) var(--space-4);
325 background: var(--surface-3);
326 border-bottom: 1px solid var(--border-subtle);
327 }
328
329 .df3-file-hd-right {
330 display: flex; align-items: center; gap: var(--space-3); margin-left: auto;
331 }
332
333 .df3-file-path {
334 font-family: var(--font-mono); font-size: 12px; font-weight: 500;
335 color: var(--color-accent-link); text-decoration: none;
336 &:hover { text-decoration: underline; }
337 }
338
339 .df3-ext {
340 font-size: 9px; font-family: var(--font-mono);
341 color: var(--text-muted); background: var(--surface-2);
342 padding: 1px 4px; border-radius: 3px;
343 }
344
345 .df3-raw-link {
346 font-size: 10px; color: var(--text-muted); text-decoration: none;
347 &:hover { color: var(--color-accent-link); }
348 }
349
350 .df3-line-stat {
351 font-family: var(--font-mono); font-size: 11px; color: var(--text-muted);
352 }
353
354 .df3-stat-add { color: #34d399; }
355 .df3-stat-del { color: #f87171; }
356
357 // Op dot
358 .df3-op-dot {
359 display: inline-flex; align-items: center; justify-content: center;
360 width: 14px; height: 14px; border-radius: 3px;
361 font-size: 10px; font-weight: 800; flex-shrink: 0;
362 &.df3-op-add { background: rgba(52,211,153,0.12); color: #34d399; }
363 &.df3-op-del { background: rgba(248,113,113,0.12); color: #f87171; }
364 &.df3-op-mod { background: rgba(251,191,36,0.12); color: #fbbf24; }
365 }
366
367 // ── Symbol panel ───────────────────────────────────────────────────────────
368 .df3-sym-panel {
369 border-bottom: 1px solid var(--border-subtle);
370 background: var(--surface-2);
371 }
372
373 .df3-sym-hd {
374 display: flex; align-items: center; gap: var(--space-2);
375 padding: var(--space-2) var(--space-4);
376 border-bottom: 1px solid var(--border-subtle);
377 }
378
379 .df3-sym-title {
380 font-size: 10px; font-weight: 600; color: var(--text-muted);
381 text-transform: uppercase; letter-spacing: .06em;
382 }
383
384 .df3-sym-count {
385 font-size: 10px; color: var(--color-accent);
386 background: var(--surface-3); padding: 1px 6px; border-radius: 10px;
387 border: 1px solid var(--color-accent)40;
388 }
389
390 .df3-sym-body { padding: var(--space-1) 0; }
391
392 .df3-sym-row {
393 display: flex; align-items: center; gap: var(--space-2);
394 padding: 3px var(--space-4);
395 &:hover { background: var(--surface-3); }
396 }
397
398 .df3-sym-top { font-weight: 500; }
399 .df3-sym-child { padding-left: var(--space-8); }
400
401 .df3-sym-indent {
402 color: var(--border-default); flex-shrink: 0;
403 display: flex; align-items: center;
404 }
405
406 .df3-sym-name {
407 font-family: var(--font-mono); font-size: 12px; color: var(--text-primary);
408 }
409
410 .df3-sym-desc {
411 font-size: 11px; color: var(--text-muted);
412 margin-left: auto; text-align: right;
413 white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 300px;
414 }
415
416 // Kind chips
417 .df3-kind {
418 font-size: 9px; font-family: var(--font-mono);
419 padding: 1px 5px; border-radius: 3px; flex-shrink: 0;
420 &.df3-k-class { background: #7c3aed20; color: #c084fc; }
421 &.df3-k-method { background: #0369a120; color: #38bdf8; }
422 &.df3-k-func { background: #065f4620; color: #34d399; }
423 &.df3-k-var { background: #78350f20; color: #fbbf24; }
424 &.df3-k-import { background: #71717a20; color: #a1a1aa; }
425 }
426
427 // ── Code diff table ────────────────────────────────────────────────────────
428 .df3-code-wrap { overflow-x: auto; }
429
430 .df3-table {
431 width: 100%; border-collapse: collapse;
432 font-family: var(--font-mono); font-size: 12px; line-height: 1.5;
433 background: var(--surface-1);
434
435 td { padding: 0 var(--space-2); white-space: pre; }
436 }
437
438 .df3-ln-sign {
439 width: 16px; text-align: center; user-select: none;
440 color: var(--text-muted); font-size: 11px;
441 }
442
443 .df3-table .df3-ln-num {
444 width: 44px; text-align: right; padding-right: var(--space-3);
445 color: var(--text-muted); user-select: none; border-right: 1px solid var(--border-subtle);
446 }
447
448 .df3-table .df3-ln-code { padding-left: var(--space-3); }
449
450 .df3-dl-add {
451 background: #14532d18;
452 .df3-ln-sign { color: #4ade80; }
453 .df3-ln-num { background: #14532d12; }
454 }
455
456 .df3-dl-del {
457 background: #7f1d1d18;
458 .df3-ln-sign { color: #f87171; }
459 .df3-ln-num { background: #7f1d1d12; }
460 }
461
462 .df3-dl-ctx { .df3-ln-sign { color: var(--border-default); } }
463
464 // Collapsed context separator
465 .df3-dl-ctx td { color: var(--text-muted); font-style: italic; }
466
467 // ── Misc ───────────────────────────────────────────────────────────────────
468 .df3-loading { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-8); color: var(--text-muted); font-size: 13px; }
469 .df3-empty { padding: var(--space-6); color: var(--text-muted); font-size: 13px; text-align: center; }
470 .df3-no-content { padding: var(--space-4); color: var(--text-muted); font-size: 12px; text-align: center; }
471
472
473 // ════════════════════════════════════════════════════════════════════════════
474
475
476 // ── Responsive ────────────────────────────────────────────────────────────────
477
478 @media (max-width: 768px) {
479 .diff-layout {
480 grid-template-columns: 1fr;
481 }
482
483 .diff-file-tree {
484 display: none;
485 }
486
487 .diff-hunk-header {
488 font-size: 11px;
489 overflow: hidden;
490 text-overflow: ellipsis;
491 white-space: nowrap;
492 }
493
494 .df3-layout {
495 grid-template-columns: 1fr;
496 }
497
498 .df3-file-tree {
499 display: none;
500 }
501
502 .diff-split-view {
503 display: block;
504 }
505
506 .diff-split-view .diff-col:first-child {
507 display: none;
508 }
509
510 .df3-header {
511 flex-direction: column;
512 align-items: flex-start;
513 gap: var(--space-2);
514 }
515 }
516
517 @media (max-width: 480px) {
518 .diff-page {
519 padding-top: var(--space-2);
520 }
521
522 .diff-commit-header-card {
523 padding: var(--space-2) var(--space-3);
524 }
525
526 .diff-filename {
527 font-size: 11px;
528 overflow: hidden;
529 text-overflow: ellipsis;
530 white-space: nowrap;
531 max-width: 200px;
532 }
533
534 .df3-stat-added,
535 .df3-stat-removed {
536 font-size: 11px;
537 }
538 }
File History 1 commit
sha256:9590cee1e0ccd6c76528f005b95d634d80f5019f0dcb7c371e149adc31d1fb65 refactor: enforce gRPC framing on all MWP wire traffic Sonnet 4.6 minor ⚠ 156 days ago