projview 1.0.0 → 1.2.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.
package/public/style.css CHANGED
@@ -1,29 +1,59 @@
1
- /* ---- projview: soft dark + a little cartoonish (catppuccin-mocha-ish) ---- */
1
+ /* ---- projview: quiet + minimal, light or dark. theme.js sets data-theme on
2
+ <html> from the user's choice (system / light / dark). ----
3
+ Token names are role slots, not colours: base = page, mantle = side panels,
4
+ crust = code wells, surface0-2 = hairlines -> muted ink, lavender/mauve =
5
+ the one accent, peach = highlights + notices. */
2
6
 
3
7
  :root {
4
- --base: #1e1e2e;
5
- --mantle: #181825;
6
- --crust: #11111b;
7
- --surface0: #2a2b3c;
8
- --surface1: #393a4d;
9
- --surface2: #494b63;
10
- --text: #cdd6f4;
11
- --subtext: #a6adc8;
12
- --overlay: #6c7086;
13
- --lavender: #b4befe;
14
- --mauve: #cba6f7;
15
- --peach: #fab387;
16
- --green: #a6e3a1;
17
- --blue: #89b4fa;
18
- --pink: #f5c2e7;
19
- --red: #f38ba8;
20
-
21
- --radius: 16px;
22
- --radius-sm: 10px;
23
- --font: "SF Pro Rounded", ui-rounded, "Nunito", "Quicksand", system-ui, -apple-system, sans-serif;
8
+ color-scheme: dark;
9
+ --base: #111113;
10
+ --mantle: #111113;
11
+ --crust: #18181b;
12
+ --surface0: #232327;
13
+ --surface1: #2f2f34;
14
+ --surface2: #4a4a52;
15
+ --text: #e4e4e7;
16
+ --subtext: #a1a1aa;
17
+ --overlay: #71717a;
18
+ --lavender: #8ab4f8;
19
+ --mauve: #8ab4f8;
20
+ --peach: #e2b86b;
21
+ --green: #81c995;
22
+ --blue: #8ab4f8;
23
+ --pink: #8ab4f8;
24
+ --red: #f28b82;
25
+ --on-accent: #111113;
26
+ --scrim: rgba(0, 0, 0, 0.5);
27
+
28
+ --radius: 8px;
29
+ --radius-sm: 6px;
30
+ --font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
24
31
  --mono: "JetBrains Mono", "Fira Code", ui-monospace, SFMono-Regular, Menlo, monospace;
25
- --shadow: 0 6px 20px rgba(0, 0, 0, 0.35);
26
- --shadow-sm: 0 3px 10px rgba(0, 0, 0, 0.28);
32
+ --shadow: 0 8px 28px rgba(0, 0, 0, 0.35);
33
+ --shadow-sm: none;
34
+ }
35
+
36
+ :root[data-theme="light"] {
37
+ color-scheme: light;
38
+ --base: #ffffff;
39
+ --mantle: #ffffff;
40
+ --crust: #f6f6f7;
41
+ --surface0: #ececee;
42
+ --surface1: #dcdce0;
43
+ --surface2: #b4b4bb;
44
+ --text: #18181b;
45
+ --subtext: #52525b;
46
+ --overlay: #8a8a93;
47
+ --lavender: #2563eb;
48
+ --mauve: #2563eb;
49
+ --peach: #b45309;
50
+ --green: #15803d;
51
+ --blue: #2563eb;
52
+ --pink: #2563eb;
53
+ --red: #dc2626;
54
+ --on-accent: #ffffff;
55
+ --scrim: rgba(24, 24, 27, 0.25);
56
+ --shadow: 0 8px 28px rgba(24, 24, 27, 0.12);
27
57
  }
28
58
 
29
59
  * { box-sizing: border-box; }
@@ -50,7 +80,7 @@ body {
50
80
  flex: 0 0 300px;
51
81
  height: 100vh;
52
82
  background: var(--mantle);
53
- border-right: 2px solid var(--surface0);
83
+ border-right: 1px solid var(--surface0);
54
84
  display: flex;
55
85
  flex-direction: column;
56
86
  }
@@ -60,17 +90,25 @@ body {
60
90
  align-items: center;
61
91
  gap: 11px;
62
92
  padding: 16px 16px;
63
- border-bottom: 2px solid var(--surface0);
93
+ border-bottom: 1px solid var(--surface0);
64
94
  }
65
95
 
66
- #brand .logo svg { display: block; filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.35)); }
96
+ #brand .logo { color: var(--text); }
97
+ #brand .logo svg { display: block; }
67
98
 
68
99
  .brand-text { display: flex; flex-direction: column; line-height: 1.25; }
69
- .wordmark { font-size: 17px; font-weight: 800; letter-spacing: 0.2px; }
70
- .wordmark .wm-proj { color: var(--lavender); }
71
- .wordmark .wm-view { color: var(--mauve); }
100
+ .theme-toggle {
101
+ margin-left: auto;
102
+ display: inline-flex; align-items: center; justify-content: center;
103
+ width: 28px; height: 28px; padding: 0;
104
+ background: none; border: 1px solid transparent; border-radius: var(--radius-sm);
105
+ color: var(--overlay); cursor: pointer;
106
+ }
107
+ .theme-toggle:hover { color: var(--text); border-color: var(--surface1); }
108
+ .theme-toggle svg { width: 15px; height: 15px; }
109
+ .wordmark { font-size: 15px; font-weight: 600; letter-spacing: 0.1px; color: var(--text); }
72
110
 
73
- .version { color: var(--overlay); font-size: 11px; font-weight: 500; letter-spacing: 0.3px; }
111
+ .version { color: var(--overlay); font-size: 11px; font-weight: 500; letter-spacing: 0.3px; white-space: nowrap; }
74
112
  .version.pulse { animation: vpulse 0.7s ease; }
75
113
  @keyframes vpulse {
76
114
  0% { color: var(--green); }
@@ -84,7 +122,7 @@ body {
84
122
  width: calc(100% - 24px);
85
123
  margin: 12px;
86
124
  padding: 8px 10px;
87
- border: 2px solid var(--surface0);
125
+ border: 1px solid var(--surface0);
88
126
  border-radius: var(--radius-sm);
89
127
  background: var(--base);
90
128
  color: var(--overlay);
@@ -93,8 +131,9 @@ body {
93
131
  cursor: pointer;
94
132
  transition: border-color 0.15s ease, color 0.15s ease;
95
133
  }
96
- .open-palette:hover { border-color: var(--mauve); color: var(--subtext); }
97
- .open-palette .op-ico { font-size: 12px; }
134
+ .open-palette:hover { border-color: var(--surface2); color: var(--subtext); }
135
+ .open-palette .op-ico { display: inline-flex; }
136
+ .open-palette .op-ico svg { width: 13px; height: 13px; }
98
137
  .open-palette .op-text { flex: 1; text-align: left; }
99
138
  .open-palette kbd, .palette kbd {
100
139
  font-family: var(--mono);
@@ -113,7 +152,7 @@ body {
113
152
 
114
153
  #side-foot {
115
154
  padding: 10px 16px;
116
- border-top: 2px solid var(--surface0);
155
+ border-top: 1px solid var(--surface0);
117
156
  color: var(--overlay);
118
157
  font-size: 11px;
119
158
  }
@@ -142,17 +181,13 @@ body {
142
181
  .row .ico svg { width: 15px; height: 15px; }
143
182
  .row.dir .ico { color: var(--subtext); }
144
183
  .row .ico-md { color: var(--overlay); }
145
- .row .ico-mmd { color: var(--mauve); }
184
+ .row .ico-mmd { color: var(--overlay); }
185
+ .row .ico-data { color: var(--overlay); }
146
186
  .row .label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
147
- .row.dir .label { font-weight: 600; color: var(--text); }
187
+ .row.dir .label { font-weight: 500; color: var(--text); }
148
188
 
149
- .row.file.active {
150
- background: linear-gradient(90deg, var(--mauve), var(--lavender));
151
- color: var(--crust);
152
- font-weight: 700;
153
- box-shadow: var(--shadow-sm);
154
- }
155
- .row.file.active .ico { color: var(--crust); }
189
+ .row.file.active { background: var(--surface0); color: var(--text); font-weight: 500; }
190
+ .row.file.active .ico { color: var(--mauve); }
156
191
 
157
192
  /* nested indentation with guide lines */
158
193
  .children {
@@ -179,7 +214,7 @@ body {
179
214
  flex-wrap: wrap;
180
215
  gap: 3px;
181
216
  padding: 12px 40px;
182
- background: rgba(30, 30, 46, 0.92);
217
+ background: color-mix(in srgb, var(--base) 90%, transparent);
183
218
  backdrop-filter: blur(6px);
184
219
  -webkit-backdrop-filter: blur(6px);
185
220
  border-bottom: 1px solid var(--surface0);
@@ -188,8 +223,8 @@ body {
188
223
  .crumb { background: none; border: none; font: inherit; color: var(--subtext); padding: 2px 5px; border-radius: 6px; }
189
224
  .crumb.root { color: var(--overlay); }
190
225
  .crumb.dir { cursor: pointer; }
191
- .crumb.dir:hover { color: var(--lavender); background: var(--surface0); }
192
- .crumb.current { color: var(--lavender); font-weight: 700; }
226
+ .crumb.dir:hover { color: var(--text); background: var(--surface0); }
227
+ .crumb.current { color: var(--text); font-weight: 500; }
193
228
  .crumb-sep { color: var(--overlay); opacity: 0.55; }
194
229
 
195
230
  #content { max-width: 880px; margin: 0 auto; padding: 30px 48px 90px; }
@@ -204,54 +239,51 @@ body {
204
239
  gap: 10px;
205
240
  text-align: center;
206
241
  }
207
- .empty-emoji { font-size: 56px; }
208
242
  .empty-state .muted { font-size: 13px; opacity: 0.8; }
209
243
 
210
244
  /* ---------------- markdown ---------------- */
211
245
 
212
246
  .markdown-body h1, .markdown-body h2, .markdown-body h3,
213
247
  .markdown-body h4, .markdown-body h5, .markdown-body h6 {
214
- color: var(--lavender);
248
+ color: var(--text);
249
+ font-weight: 600;
215
250
  line-height: 1.3;
216
251
  margin: 1.6em 0 0.6em;
217
252
  scroll-margin-top: 56px; /* clear the sticky breadcrumb when an #anchor jumps here */
218
253
  }
219
- .markdown-body h1 { font-size: 2em; border-bottom: 2px solid var(--surface0); padding-bottom: 0.3em; }
220
- .markdown-body h2 { font-size: 1.5em; border-bottom: 1px solid var(--surface0); padding-bottom: 0.25em; }
221
- .markdown-body h3 { font-size: 1.25em; color: var(--mauve); }
254
+ .markdown-body h1 { font-size: 1.85em; border-bottom: 1px solid var(--surface0); padding-bottom: 0.3em; }
255
+ .markdown-body h2 { font-size: 1.4em; border-bottom: 1px solid var(--surface0); padding-bottom: 0.25em; }
256
+ .markdown-body h3 { font-size: 1.15em; }
222
257
 
223
- .markdown-body a { color: var(--blue); text-decoration: none; border-bottom: 1px dashed var(--blue); }
224
- .markdown-body a:hover { color: var(--pink); border-bottom-color: var(--pink); }
258
+ .markdown-body a { color: var(--blue); text-decoration: underline; text-decoration-color: color-mix(in srgb, var(--blue) 40%, transparent); text-underline-offset: 2px; }
259
+ .markdown-body a:hover { text-decoration-color: var(--blue); }
225
260
 
226
261
  .markdown-body p, .markdown-body li { color: var(--text); }
227
- .markdown-body strong { color: var(--peach); }
262
+ .markdown-body strong { font-weight: 600; }
228
263
 
229
264
  .markdown-body code {
230
265
  font-family: var(--mono);
231
266
  font-size: 0.88em;
232
267
  background: var(--surface0);
233
268
  padding: 2px 6px;
234
- border-radius: 6px;
235
- color: var(--peach);
269
+ border-radius: 4px;
270
+ color: var(--text);
236
271
  }
237
272
 
238
273
  .markdown-body pre,
239
274
  .markdown-body pre.hljs {
240
275
  background: var(--crust) !important;
241
- border: 2px solid var(--surface0);
276
+ border: 1px solid var(--surface0);
242
277
  border-radius: var(--radius);
243
- padding: 16px 18px;
278
+ padding: 14px 16px;
244
279
  overflow-x: auto;
245
- box-shadow: var(--shadow-sm);
246
280
  }
247
281
  .markdown-body pre code { background: none; padding: 0; color: inherit; font-size: 0.86em; }
248
282
 
249
283
  .markdown-body blockquote {
250
284
  margin: 1em 0;
251
285
  padding: 4px 18px;
252
- border-left: 4px solid var(--mauve);
253
- background: var(--mantle);
254
- border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
286
+ border-left: 3px solid var(--surface1);
255
287
  color: var(--subtext);
256
288
  }
257
289
 
@@ -259,37 +291,66 @@ body {
259
291
  border-collapse: collapse;
260
292
  width: 100%;
261
293
  margin: 1em 0;
262
- border-radius: var(--radius-sm);
263
- overflow: hidden;
264
- box-shadow: var(--shadow-sm);
265
294
  }
266
295
  .markdown-body th, .markdown-body td {
267
296
  border: 1px solid var(--surface0);
268
297
  padding: 9px 14px;
269
298
  }
270
- .markdown-body th { background: var(--surface0); color: var(--lavender); }
271
- .markdown-body tr:nth-child(even) td { background: var(--mantle); }
299
+ .markdown-body th { background: var(--crust); font-weight: 600; text-align: left; }
272
300
 
273
- .markdown-body hr { border: none; border-top: 2px dashed var(--surface1); margin: 2em 0; }
301
+ .markdown-body hr { border: none; border-top: 1px solid var(--surface0); margin: 2em 0; }
274
302
 
275
303
  .markdown-body img { max-width: 100%; border-radius: var(--radius-sm); }
276
304
 
277
305
  .markdown-body ul, .markdown-body ol { padding-left: 1.5em; }
278
306
 
307
+ /* json / yaml code view: line numbers + one indent guide per level */
308
+ .markdown-body pre.code-view { padding: 14px 0; line-height: 1.6; counter-reset: ln; }
309
+ .markdown-body pre.code-view code { display: block; min-width: max-content; }
310
+ .code-view .cl { display: flex; min-height: 1.6em; padding-right: 18px; }
311
+ .code-view .cl::before {
312
+ counter-increment: ln;
313
+ content: counter(ln);
314
+ flex: 0 0 5ch;
315
+ padding-right: 1.5ch;
316
+ margin-right: 1.5ch;
317
+ text-align: right;
318
+ color: var(--surface2);
319
+ border-right: 1px solid var(--surface0);
320
+ user-select: none;
321
+ }
322
+ .code-view .cl[data-toc] { scroll-margin-top: 56px; } /* clear the sticky breadcrumb on #anchor jumps */
323
+ .code-view .cl:hover { background: color-mix(in srgb, var(--mauve) 6%, transparent); }
324
+ .code-view .cl:hover::before { color: var(--overlay); }
325
+ .code-view .lc {
326
+ white-space: pre;
327
+ background-image: repeating-linear-gradient(90deg,
328
+ var(--surface2) 0 1px, transparent 1px calc(var(--step) * 1ch));
329
+ background-size: calc(var(--i) * 1ch) 100%;
330
+ background-repeat: no-repeat;
331
+ }
332
+ .data-notice {
333
+ margin: 0 0 12px;
334
+ padding: 8px 14px;
335
+ border: 1px solid var(--peach);
336
+ border-radius: var(--radius-sm);
337
+ background: color-mix(in srgb, var(--peach) 7%, transparent);
338
+ color: var(--peach);
339
+ font-size: 0.85em;
340
+ }
341
+
279
342
  /* mermaid card */
280
343
  .mermaid {
281
344
  display: flex;
282
345
  justify-content: center;
283
- background: var(--mantle);
284
- border: 2px solid var(--surface0);
346
+ border: 1px solid var(--surface0);
285
347
  border-radius: var(--radius);
286
- padding: 22px;
348
+ padding: 20px;
287
349
  margin: 1.4em 0;
288
- box-shadow: var(--shadow-sm);
289
350
  }
290
351
  .mermaid svg { max-width: 100%; height: auto; }
291
352
  .mermaid.rendered { cursor: zoom-in; }
292
- .mermaid.mermaid-error { display: block; border-color: var(--red); background: rgba(243, 139, 168, 0.06); }
353
+ .mermaid.mermaid-error { display: block; border-color: var(--red); background: color-mix(in srgb, var(--red) 6%, transparent); }
293
354
  .diagram-error { color: var(--red); width: 100%; text-align: left; }
294
355
  .diagram-error .err-msg {
295
356
  margin: 8px 0;
@@ -310,7 +371,7 @@ body {
310
371
  width: 240px;
311
372
  height: 100vh;
312
373
  background: var(--mantle);
313
- border-left: 2px solid var(--surface0);
374
+ border-left: 1px solid var(--surface0);
314
375
  display: flex;
315
376
  flex-direction: column;
316
377
  overflow: hidden;
@@ -353,10 +414,10 @@ body {
353
414
  transition: color 0.12s, background 0.12s, border-color 0.12s;
354
415
  }
355
416
  .toc-item:hover { color: var(--text); background: var(--surface0); }
356
- .toc-item.lvl-h1 { font-weight: 700; color: var(--text); }
417
+ .toc-item.lvl-h1 { font-weight: 500; color: var(--text); }
357
418
  .toc-item.lvl-h2 { padding-left: 18px; }
358
419
  .toc-item.lvl-h3 { padding-left: 30px; font-size: 12px; }
359
- .toc-item.active { color: var(--lavender); border-left-color: var(--mauve); background: var(--surface0); }
420
+ .toc-item.active { color: var(--text); border-left-color: var(--mauve); }
360
421
 
361
422
  #toc-reopen {
362
423
  position: fixed;
@@ -365,19 +426,40 @@ body {
365
426
  display: none;
366
427
  width: 34px; height: 34px;
367
428
  border-radius: 9px;
368
- border: 2px solid var(--surface0);
429
+ border: 1px solid var(--surface0);
369
430
  background: var(--mantle);
370
431
  color: var(--subtext);
371
432
  cursor: pointer;
372
433
  font-size: 15px;
373
434
  }
374
- #toc-reopen:hover { color: var(--lavender); border-color: var(--mauve); }
435
+ #toc-reopen:hover { color: var(--text); border-color: var(--surface2); }
375
436
 
376
437
  body.toc-collapsed #toc { display: none; }
377
438
  body.toc-collapsed #toc-reopen { display: block; }
378
439
  body.toc-empty #toc { display: none; }
379
440
  body.toc-empty #toc-reopen { display: none; }
380
441
 
442
+ /* ---------------- narrow windows ---------------- */
443
+
444
+ /* the page is the point: the outline goes first, then the side panel slims down */
445
+ @media (max-width: 1100px) {
446
+ /* the outline becomes an overlay you open from the corner button */
447
+ #toc { display: none; position: fixed; top: 0; right: 0; z-index: 25; box-shadow: var(--shadow); }
448
+ #toc-reopen { display: block; }
449
+ body.toc-open #toc { display: flex; }
450
+ body.toc-open #toc-reopen, body.toc-empty #toc-reopen, body.toc-empty #toc { display: none; }
451
+ }
452
+ @media (max-width: 800px) {
453
+ #sidebar { width: 220px; flex-basis: 220px; }
454
+ #breadcrumb { padding: 10px 16px; }
455
+ #content { padding: 20px 20px 60px; }
456
+ }
457
+ @media (max-width: 560px) {
458
+ #sidebar { width: 170px; flex-basis: 170px; }
459
+ .open-palette kbd, #side-foot { display: none; }
460
+ }
461
+ #viewer { min-width: 0; } /* let wide code scroll inside the page instead of pushing the layout */
462
+
381
463
  /* ---------------- search palette (cmd+K) ---------------- */
382
464
 
383
465
  .palette {
@@ -388,9 +470,7 @@ body.toc-empty #toc-reopen { display: none; }
388
470
  justify-content: center;
389
471
  align-items: flex-start;
390
472
  padding-top: 12vh;
391
- background: rgba(17, 17, 27, 0.55);
392
- backdrop-filter: blur(3px);
393
- -webkit-backdrop-filter: blur(3px);
473
+ background: var(--scrim);
394
474
  }
395
475
  .palette[hidden] { display: none; }
396
476
  .palette-box {
@@ -399,7 +479,7 @@ body.toc-empty #toc-reopen { display: none; }
399
479
  display: flex;
400
480
  flex-direction: column;
401
481
  background: var(--mantle);
402
- border: 2px solid var(--surface1);
482
+ border: 1px solid var(--surface1);
403
483
  border-radius: var(--radius);
404
484
  box-shadow: var(--shadow);
405
485
  overflow: hidden;
@@ -407,7 +487,7 @@ body.toc-empty #toc-reopen { display: none; }
407
487
  #palette-input {
408
488
  padding: 16px 18px;
409
489
  border: none;
410
- border-bottom: 2px solid var(--surface0);
490
+ border-bottom: 1px solid var(--surface0);
411
491
  background: transparent;
412
492
  color: var(--text);
413
493
  font-family: inherit;
@@ -431,8 +511,8 @@ body.toc-empty #toc-reopen { display: none; }
431
511
  .pr-ico { flex: 0 0 15px; height: 15px; color: var(--overlay); display: inline-flex; align-items: center; }
432
512
  .pr-ico svg { width: 15px; height: 15px; }
433
513
  .presult.sel .pr-ico { color: var(--mauve); }
434
- .pr-name { color: var(--text); font-size: 14px; font-weight: 600; }
435
- .pr-badge { color: var(--peach); font-size: 11px; font-family: var(--mono); }
514
+ .pr-name { color: var(--text); font-size: 14px; font-weight: 500; }
515
+ .pr-badge { color: var(--overlay); font-size: 11px; font-family: var(--mono); }
436
516
  .pr-path {
437
517
  margin-left: auto;
438
518
  color: var(--overlay);
@@ -453,25 +533,25 @@ body.toc-empty #toc-reopen { display: none; }
453
533
  text-overflow: ellipsis;
454
534
  }
455
535
  .snip-ln { color: var(--overlay); margin-right: 8px; }
456
- .palette mark { background: transparent; color: var(--peach); font-weight: 700; padding: 0; }
536
+ .palette mark { background: transparent; color: var(--text); font-weight: 600; text-decoration: underline; text-decoration-color: var(--mauve); text-underline-offset: 2px; padding: 0; }
457
537
  .palette-foot {
458
538
  display: flex;
459
539
  gap: 16px;
460
540
  padding: 8px 14px;
461
- border-top: 2px solid var(--surface0);
541
+ border-top: 1px solid var(--surface0);
462
542
  color: var(--overlay);
463
543
  font-size: 11px;
464
544
  }
465
545
 
466
546
  /* in-content highlight when opening a search hit */
467
547
  mark.search-hit {
468
- background: var(--peach);
469
- color: var(--crust);
548
+ background: color-mix(in srgb, var(--peach) 35%, transparent);
549
+ color: inherit;
470
550
  border-radius: 3px;
471
551
  padding: 0 2px;
472
552
  animation: hitflash 0.45s ease;
473
553
  }
474
- @keyframes hitflash { from { background: var(--green); } to { background: var(--peach); } }
554
+ @keyframes hitflash { from { background: color-mix(in srgb, var(--peach) 70%, transparent); } }
475
555
 
476
556
  /* ---------------- toast ---------------- */
477
557
 
@@ -481,9 +561,9 @@ mark.search-hit {
481
561
  left: 50%;
482
562
  transform: translateX(-50%) translateY(12px);
483
563
  z-index: 50;
484
- background: var(--surface1);
564
+ background: var(--base);
485
565
  color: var(--text);
486
- border: 2px solid var(--surface2);
566
+ border: 1px solid var(--surface1);
487
567
  border-radius: var(--radius-sm);
488
568
  padding: 10px 16px;
489
569
  font-size: 13px;
@@ -504,7 +584,7 @@ mark.search-hit {
504
584
  align-items: center;
505
585
  justify-content: center;
506
586
  overflow: hidden;
507
- background: rgba(17, 17, 27, 0.93);
587
+ background: color-mix(in srgb, var(--base) 95%, transparent);
508
588
  }
509
589
  .zoom-overlay[hidden] { display: none; }
510
590
  .zoom-hint {
@@ -527,7 +607,7 @@ mark.search-hit {
527
607
 
528
608
  /* scrollbars */
529
609
  ::-webkit-scrollbar { width: 11px; height: 11px; }
530
- ::-webkit-scrollbar-thumb { background: var(--surface1); border-radius: 20px; border: 2px solid var(--mantle); }
610
+ ::-webkit-scrollbar-thumb { background: var(--surface1); border-radius: 20px; border: 3px solid var(--base); }
531
611
  ::-webkit-scrollbar-thumb:hover { background: var(--surface2); }
532
612
  ::-webkit-scrollbar-track { background: transparent; }
533
613
 
@@ -538,74 +618,74 @@ mark.search-hit {
538
618
 
539
619
  .cmt-fab {
540
620
  position: fixed; bottom: 22px; right: 22px; z-index: 30;
541
- width: 52px; height: 52px; border-radius: 50%;
542
- border: 2px solid var(--surface1); background: var(--mauve); color: var(--crust);
543
- font-size: 21px; cursor: pointer; box-shadow: var(--shadow);
621
+ width: 44px; height: 44px; border-radius: 50%;
622
+ border: 1px solid var(--surface1); background: var(--base); color: var(--subtext);
623
+ font-size: 18px; cursor: pointer; box-shadow: var(--shadow);
544
624
  display: flex; align-items: center; justify-content: center;
545
625
  transition: transform 0.15s ease, background 0.15s ease;
546
626
  }
547
- .cmt-fab:hover { transform: translateY(-2px); }
548
- .cmt-fab.open { background: var(--lavender); }
627
+ .cmt-fab:hover { color: var(--text); border-color: var(--surface2); }
628
+ .cmt-fab.open { color: var(--mauve); border-color: var(--mauve); }
549
629
  .cmt-fab[hidden] { display: none; }
550
630
  .cmt-badge {
551
631
  position: absolute; top: -4px; right: -4px;
552
632
  min-width: 20px; height: 20px; padding: 0 5px; border-radius: 10px;
553
- background: var(--red); color: var(--crust);
554
- font-size: 11px; font-weight: 800; line-height: 20px; border: 2px solid var(--base);
633
+ background: var(--mauve); color: var(--on-accent);
634
+ font-size: 11px; font-weight: 600; line-height: 20px; border: 2px solid var(--base);
555
635
  }
556
636
 
557
637
  .cmt-drawer {
558
638
  position: fixed; top: 0; right: 0; z-index: 29;
559
639
  width: 360px; max-width: 90vw; height: 100vh;
560
- background: var(--mantle); border-left: 2px solid var(--surface0);
561
- box-shadow: -8px 0 28px rgba(0, 0, 0, 0.4);
640
+ background: var(--mantle); border-left: 1px solid var(--surface0);
641
+ box-shadow: var(--shadow);
562
642
  display: flex; flex-direction: column;
563
643
  }
564
644
  .cmt-drawer[hidden] { display: none; }
565
645
  .cmt-drawer-head {
566
646
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
567
- padding: 16px 16px 12px; border-bottom: 2px solid var(--surface0);
647
+ padding: 16px 16px 12px; border-bottom: 1px solid var(--surface0);
568
648
  }
569
- .cmt-drawer-head strong { color: var(--mauve); }
649
+ .cmt-drawer-head strong { color: var(--text); font-weight: 600; }
570
650
  .cmt-file { color: var(--overlay); font-size: 12px; }
571
651
  .cmt-head-btns { display: flex; gap: 6px; }
572
652
  .cmt-add-file, .cmt-close {
573
653
  background: var(--surface0); border: none; color: var(--subtext);
574
654
  border-radius: 8px; padding: 5px 9px; cursor: pointer; font: inherit; font-size: 12px;
575
655
  }
576
- .cmt-add-file:hover { background: var(--surface1); color: var(--green); }
656
+ .cmt-add-file:hover { background: var(--surface1); color: var(--text); }
577
657
  .cmt-close:hover { background: var(--surface1); color: var(--text); }
578
658
 
579
659
  .cmt-composer-slot:not(:empty) { padding: 12px; border-bottom: 1px solid var(--surface0); }
580
660
  .cmt-composer { display: flex; flex-direction: column; gap: 8px; }
581
661
  .cmt-composer textarea {
582
662
  width: 100%; resize: vertical; background: var(--base); color: var(--text);
583
- border: 2px solid var(--surface1); border-radius: var(--radius-sm);
663
+ border: 1px solid var(--surface1); border-radius: var(--radius-sm);
584
664
  padding: 8px 10px; font: inherit; font-size: 13px;
585
665
  }
586
- .cmt-composer textarea:focus { outline: none; border-color: var(--mauve); }
666
+ .cmt-composer textarea:focus { outline: none; border-color: var(--surface2); }
587
667
  .cmt-composer-actions { display: flex; gap: 8px; }
588
668
  .cmt-btn {
589
- border: 2px solid var(--surface1); background: var(--surface0); color: var(--subtext);
669
+ border: 1px solid var(--surface1); background: var(--surface0); color: var(--subtext);
590
670
  border-radius: 8px; padding: 5px 12px; cursor: pointer; font: inherit; font-size: 12.5px;
591
671
  }
592
672
  .cmt-btn:hover { color: var(--text); }
593
- .cmt-btn.primary { background: var(--mauve); border-color: var(--mauve); color: var(--crust); font-weight: 700; }
594
- .cmt-btn.primary:hover { background: var(--lavender); border-color: var(--lavender); }
673
+ .cmt-btn.primary { background: var(--mauve); border-color: var(--mauve); color: var(--on-accent); font-weight: 500; }
674
+ .cmt-btn.primary:hover { opacity: 0.9; }
595
675
 
596
676
  .cmt-list { flex: 1; overflow-y: auto; padding: 10px 12px 24px; display: flex; flex-direction: column; gap: 10px; }
597
677
  .cmt-empty { text-align: center; color: var(--overlay); padding: 36px 10px; font-size: 13px; line-height: 1.9; }
598
678
  .cmt-card {
599
- background: var(--base); border: 2px solid var(--surface0); border-radius: var(--radius-sm);
679
+ background: var(--base); border: 1px solid var(--surface0); border-radius: var(--radius-sm);
600
680
  padding: 10px 12px; cursor: pointer; transition: border-color 0.12s ease;
601
681
  }
602
682
  .cmt-card:hover { border-color: var(--surface2); }
603
- .cmt-card.active { border-color: var(--peach); }
683
+ .cmt-card.active { border-color: var(--mauve); }
604
684
  .cmt-card.resolved { opacity: 0.6; }
605
685
  .cmt-card.resolved .cmt-body { text-decoration: line-through; text-decoration-color: var(--overlay); }
606
686
  .cmt-card.orphan { border-style: dashed; }
607
687
  .cmt-meta { display: flex; justify-content: space-between; align-items: baseline; font-size: 11.5px; margin-bottom: 6px; }
608
- .cmt-author { color: var(--blue); font-weight: 700; }
688
+ .cmt-author { color: var(--text); font-weight: 600; }
609
689
  .cmt-time { color: var(--overlay); }
610
690
  .cmt-anchor-chip {
611
691
  display: block; background: var(--surface0); color: var(--subtext);
@@ -616,21 +696,169 @@ mark.search-hit {
616
696
  .cmt-body { font-size: 13px; color: var(--text); word-break: break-word; }
617
697
  .cmt-actions { display: flex; gap: 14px; margin-top: 9px; }
618
698
  .cmt-link { background: none; border: none; color: var(--overlay); cursor: pointer; font: inherit; font-size: 11.5px; padding: 0; }
619
- .cmt-link:hover { color: var(--lavender); }
699
+ .cmt-link:hover { color: var(--text); }
620
700
  .cmt-link.danger:hover { color: var(--red); }
621
701
 
622
702
  .cmt-selchip {
623
- position: fixed; z-index: 40; background: var(--mauve); color: var(--crust);
624
- border: none; border-radius: 8px; padding: 5px 10px;
625
- font: inherit; font-size: 12px; font-weight: 700; cursor: pointer; box-shadow: var(--shadow-sm);
703
+ position: fixed; z-index: 40; background: var(--base); color: var(--text);
704
+ border: 1px solid var(--surface1); border-radius: var(--radius-sm); padding: 4px 10px;
705
+ font: inherit; font-size: 12px; font-weight: 500; cursor: pointer; box-shadow: var(--shadow);
626
706
  }
627
- .cmt-selchip:hover { background: var(--lavender); }
707
+ .cmt-selchip:hover { border-color: var(--surface2); }
628
708
 
629
709
  .markdown-body h1, .markdown-body h2, .markdown-body h3 { position: relative; }
630
710
  .cmt-head-add {
631
- border: none; background: none; cursor: pointer; font-size: 0.62em;
632
- opacity: 0; margin-left: 8px; vertical-align: middle; transition: opacity 0.12s ease;
711
+ border: none; background: none; cursor: pointer; font: inherit; font-size: 0.55em; font-weight: 500;
712
+ color: var(--overlay); opacity: 0; margin-left: 8px; vertical-align: middle; transition: opacity 0.12s ease;
633
713
  }
634
- .cmt-head-add::before { content: '💬'; }
714
+ .cmt-head-add::before { content: '+ comment'; }
635
715
  h1:hover > .cmt-head-add, h2:hover > .cmt-head-add, h3:hover > .cmt-head-add { opacity: 0.5; }
636
716
  .cmt-head-add:hover { opacity: 1 !important; }
717
+
718
+ /* ---------------- source editor ---------------- */
719
+
720
+ .view-switch {
721
+ margin-left: auto;
722
+ display: inline-flex;
723
+ border: 1px solid var(--surface1); border-radius: var(--radius-sm);
724
+ overflow: hidden;
725
+ }
726
+ .view-switch button {
727
+ background: none; border: none; border-left: 1px solid var(--surface1);
728
+ color: var(--overlay); font: inherit; font-size: 12px; padding: 2px 10px; cursor: pointer;
729
+ }
730
+ .view-switch button:first-child { border-left: none; }
731
+ .view-switch button:hover { color: var(--text); }
732
+ .view-switch button.on { background: var(--surface0); color: var(--text); }
733
+
734
+ body.editing #toc, body.editing #toc-reopen, body.editing .cmt-fab, body.editing .cmt-drawer { display: none; }
735
+ body.editing #content { max-width: none; padding-bottom: 30px; }
736
+ body.editing .cmt-selchip { display: none; }
737
+
738
+ .editor { display: flex; flex-direction: column; gap: 10px; height: calc(100vh - 120px); }
739
+ .editor-bar { display: flex; align-items: center; gap: 10px; font-size: 13px; }
740
+ .editor-name { color: var(--text); font-weight: 600; }
741
+ .editor-dirty { color: var(--peach); font-size: 12px; }
742
+ .editor-spacer { flex: 1; }
743
+ .editor-hint { color: var(--overlay); font-size: 12px; }
744
+ .editor-btn {
745
+ background: none; border: 1px solid var(--surface1); border-radius: var(--radius-sm);
746
+ color: var(--subtext); font: inherit; font-size: 12.5px; padding: 4px 12px; cursor: pointer;
747
+ }
748
+ .editor-btn:hover { color: var(--text); border-color: var(--surface2); }
749
+ .editor-btn.primary { background: var(--mauve); border-color: var(--mauve); color: var(--on-accent); font-weight: 500; }
750
+ .editor-btn.primary:hover { opacity: 0.9; }
751
+ .editor-notice {
752
+ display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
753
+ padding: 8px 12px; border: 1px solid var(--peach); border-radius: var(--radius-sm);
754
+ background: color-mix(in srgb, var(--peach) 7%, transparent); color: var(--peach); font-size: 12.5px;
755
+ }
756
+ .editor-notice[hidden] { display: none; }
757
+ .editor-panes {
758
+ flex: 1; min-height: 0;
759
+ display: grid; grid-template-columns: var(--split, 50%) 10px minmax(0, 1fr);
760
+ }
761
+ .editor-panes.resizing { cursor: col-resize; user-select: none; }
762
+ .editor-divider { cursor: col-resize; position: relative; }
763
+ .editor-divider::after {
764
+ content: ''; position: absolute; top: 0; bottom: 0; left: 4px; width: 2px;
765
+ border-radius: 2px; background: transparent; transition: background 0.12s ease;
766
+ }
767
+ .editor-divider:hover::after, .editor-divider:focus-visible::after,
768
+ .editor-panes.resizing .editor-divider::after { background: var(--mauve); }
769
+ .editor-divider:focus { outline: none; }
770
+ .editor-preview {
771
+ min-width: 0; overflow: auto;
772
+ border: 1px solid var(--surface0); border-radius: var(--radius);
773
+ padding: 4px 24px 24px;
774
+ }
775
+ .editor-preview > :first-child { margin-top: 18px; }
776
+ @media (max-width: 800px) {
777
+ .editor-panes { grid-template-columns: 1fr; grid-template-rows: 1fr 1fr; gap: 10px; }
778
+ .editor-divider { display: none; }
779
+ }
780
+ .editor-text {
781
+ width: 100%; height: 100%; min-width: 0; resize: none;
782
+ background: var(--crust); color: var(--text);
783
+ border: 1px solid var(--surface0); border-radius: var(--radius);
784
+ padding: 14px 16px; font-family: var(--mono); font-size: 13px; line-height: 1.6; tab-size: 2;
785
+ white-space: pre; overflow: auto;
786
+ }
787
+ .editor-text:focus { outline: none; border-color: var(--surface2); }
788
+
789
+ /* ---------------- history ---------------- */
790
+
791
+ body.history #toc, body.history #toc-reopen { display: none !important; }
792
+ body.history #content { max-width: none; padding-bottom: 30px; }
793
+ .history-view { display: flex; flex-direction: column; gap: 10px; height: calc(100vh - 120px); }
794
+ .history-bar { display: flex; align-items: baseline; gap: 12px; font-size: 13px; }
795
+ .history-name { color: var(--text); font-weight: 600; }
796
+ .history-hint { color: var(--overlay); font-size: 12px; }
797
+ .history-panes { flex: 1; min-height: 0; display: grid; grid-template-columns: 210px minmax(0, 1fr); gap: 14px; }
798
+ .history-list { display: flex; flex-direction: column; gap: 2px; overflow-y: auto; }
799
+ .history-item {
800
+ display: flex; justify-content: space-between; align-items: baseline; gap: 8px;
801
+ padding: 7px 10px; border: none; border-radius: var(--radius-sm);
802
+ background: none; color: var(--subtext); font: inherit; font-size: 13px; text-align: left; cursor: pointer;
803
+ }
804
+ .history-item:hover { background: var(--surface0); color: var(--text); }
805
+ .history-item[aria-current="true"] { background: var(--surface0); color: var(--text); box-shadow: inset 2px 0 0 var(--mauve); }
806
+ .hi-label { display: flex; flex-direction: column; }
807
+ .hi-label small { color: var(--overlay); font-size: 11px; }
808
+ .hi-size { color: var(--overlay); font-size: 11px; font-family: var(--mono); }
809
+ .history-empty { color: var(--overlay); font-size: 12px; line-height: 1.5; padding: 8px 10px; margin: 0; }
810
+ .history-pane { min-width: 0; display: flex; flex-direction: column; border: 1px solid var(--surface0); border-radius: var(--radius); overflow: hidden; }
811
+ .history-pane-bar {
812
+ display: flex; align-items: center; justify-content: space-between; gap: 10px;
813
+ padding: 8px 14px; border-bottom: 1px solid var(--surface0); color: var(--subtext); font-size: 12.5px;
814
+ }
815
+ .history-preview { flex: 1; overflow: auto; padding: 4px 24px 24px; }
816
+ .history-preview > :first-child { margin-top: 18px; }
817
+ @media (max-width: 800px) {
818
+ .history-panes { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
819
+ .history-list { flex-direction: row; overflow-x: auto; }
820
+ }
821
+
822
+ /* ---------------- syntax colours in light mode (vendor theme is github-dark) ---------------- */
823
+
824
+ :root[data-theme="light"] .hljs { color: #24292e; background: var(--crust); }
825
+ :root[data-theme="light"] .hljs-doctag,
826
+ :root[data-theme="light"] .hljs-keyword,
827
+ :root[data-theme="light"] .hljs-meta .hljs-keyword,
828
+ :root[data-theme="light"] .hljs-template-tag,
829
+ :root[data-theme="light"] .hljs-template-variable,
830
+ :root[data-theme="light"] .hljs-type,
831
+ :root[data-theme="light"] .hljs-variable.language_ { color: #d73a49; }
832
+ :root[data-theme="light"] .hljs-title,
833
+ :root[data-theme="light"] .hljs-title.class_,
834
+ :root[data-theme="light"] .hljs-title.class_.inherited__,
835
+ :root[data-theme="light"] .hljs-title.function_ { color: #6f42c1; }
836
+ :root[data-theme="light"] .hljs-attr,
837
+ :root[data-theme="light"] .hljs-attribute,
838
+ :root[data-theme="light"] .hljs-literal,
839
+ :root[data-theme="light"] .hljs-meta,
840
+ :root[data-theme="light"] .hljs-number,
841
+ :root[data-theme="light"] .hljs-operator,
842
+ :root[data-theme="light"] .hljs-selector-attr,
843
+ :root[data-theme="light"] .hljs-selector-class,
844
+ :root[data-theme="light"] .hljs-selector-id,
845
+ :root[data-theme="light"] .hljs-variable { color: #005cc5; }
846
+ :root[data-theme="light"] .hljs-meta .hljs-string,
847
+ :root[data-theme="light"] .hljs-regexp,
848
+ :root[data-theme="light"] .hljs-string { color: #032f62; }
849
+ :root[data-theme="light"] .hljs-built_in,
850
+ :root[data-theme="light"] .hljs-symbol { color: #e36209; }
851
+ :root[data-theme="light"] .hljs-code,
852
+ :root[data-theme="light"] .hljs-comment,
853
+ :root[data-theme="light"] .hljs-formula { color: #6a737d; }
854
+ :root[data-theme="light"] .hljs-name,
855
+ :root[data-theme="light"] .hljs-quote,
856
+ :root[data-theme="light"] .hljs-selector-pseudo,
857
+ :root[data-theme="light"] .hljs-selector-tag { color: #22863a; }
858
+ :root[data-theme="light"] .hljs-subst,
859
+ :root[data-theme="light"] .hljs-emphasis,
860
+ :root[data-theme="light"] .hljs-strong { color: #24292e; }
861
+ :root[data-theme="light"] .hljs-section { color: #005cc5; }
862
+ :root[data-theme="light"] .hljs-bullet { color: #735c0f; }
863
+ :root[data-theme="light"] .hljs-addition { color: #22863a; background-color: #f0fff4; }
864
+ :root[data-theme="light"] .hljs-deletion { color: #b31d28; background-color: #ffeef0; }